package com.evanflare.conf;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Map;

/**
 * @author Yanion_gwgzh
 * 定义配置文件的位置
 * 检测配置文件是否正常并处理异常情况
 *
 * 这里有一个单例设计
 */
public class ReadConfig {
    public static ReadConfig getInstance(){
        return INSTANCE;
    }
    private static final ReadConfig INSTANCE = new ReadConfig();
    public static final String CONFIG_FILE_PATH ="./configuration.yaml";
    public static final String[] CONFIG_KEYS = ConfigKeysConstant.getKeys();
    private static final Logger LOGGER = LoggerFactory.getLogger(ReadConfig.class);
    private static Map<String, Object> configData;
    static{
        // 1 检测配置文件是否存在，不存在则自动创建
        File configFile = new File(CONFIG_FILE_PATH);
        while (!configFile.exists()){
            // 1.2 如果不存在，则自动创建
            LOGGER.info("检测配置文件不存在，试图新建配置文件。");
            try {
                configFile.createNewFile();
                // 1.2.1 填入默认内容
                StringBuilder builder = new StringBuilder();
                for (String key : CONFIG_KEYS) {
                    builder.append(key).append(": ").append(ConfigKeysConstant.valueOf(key).getDefaultValue()).append(System.lineSeparator());
                }
                try( FileOutputStream fileOutputStream = new FileOutputStream(configFile);
                    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream)){
                    bufferedOutputStream.write(builder.toString().getBytes(StandardCharsets.UTF_8));
                }
            } catch (IOException e) {
                // 1.2.1 无法创建配置文件，返回错误信息并退出。
                LOGGER.error("fatal: 无法创建配置文件{}。", CONFIG_FILE_PATH);
                System.exit(-1);
            }
            LOGGER.info("新建配置文件成功。");
        }
        LOGGER.info("检测到配置文件。");
        // 2 遍历配置文件的重要参数，判断是否合法
        // 读取 YAML 文件
        try (InputStream inputStream = new FileInputStream(configFile)) {
            Yaml yaml = new Yaml();
            Map<String, Object> data = yaml.load(inputStream);
            // 2.1 读取数据
            LOGGER.info("configuration all data: {}", data);
            // 2.1.1 检验数据
            if (data == null || !data.keySet().containsAll(Arrays.asList(CONFIG_KEYS))) {
                // 2.1.1 没有包含所有的配置参数
                LOGGER.error("fatal: 配置文件数据不全，请补全所有参数，或者删除错误的配置文件，将自动生成默认配置文件。");
                System.exit(-1);
            }
            configData = data;
        } catch (IOException e) {
            LOGGER.error("fatal: 无法编辑配置文件！{}", e.toString());
            e.printStackTrace();
            System.exit(-1);
        }
    }

    /**
     * 通过这个方法获取配置文件中的值
     * @param key 参数名
     * @return 返回配置文件中的值，不存在则返回系统默认值
     */
    public String getConfigValue(String key){
        String res = (String) configData.get(key);
        if(res == null || res.isEmpty()){
            res = ConfigKeysConstant.valueOf(key).getDefaultValue();
        }
        return res;
    }
}
